package com.wx.utils;

import com.alibaba.fastjson.JSONObject;
import com.thoughtworks.xstream.XStream;
import com.wx.config.UserConfig;
import com.wx.entity.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * @author DKH
 * @version 1.0.0
 * @createTime 2022年01月27日 13:52:00
 */

@Component
@Data
@Slf4j
public class MessageUtil {


    @Autowired
    private TemplateMessage templateMessage;
    @Autowired
    private StringUtil stringUtil;

    @Autowired
    private UserConfig config;


    private String text = "世界如此美丽，我却只为你着迷";


    private String getAccessToken() {
        HttpClient instance = HttpClient.getInstance();
        JSONObject jsonObject = JSONObject.parseObject(instance.get(BaseUrl.ACCESS_TOKEN_URL.replace("APPID", config.getAppId()).replace("APPSECRET", config.getAppSecret())));
        return jsonObject.get("access_token").toString();
    }

    /**
     * 返回消息类型：文本
     */
    public static final String RESP_MESSAGE_TYPE_TEXT = "text";

    /**
     * 返回消息类型：音乐
     */
    public static final String RESP_MESSAGE_TYPE_MUSIC = "music";

    /**
     * 返回消息类型：图文
     */
    public static final String RESP_MESSAGE_TYPE_NEWS = "news";

    /**
     * 返回消息类型：图片
     */
    public static final String RESP_MESSAGE_TYPE_Image = "image";

    /**
     * 返回消息类型：语音
     */
    public static final String RESP_MESSAGE_TYPE_Voice = "voice";

    /**
     * 返回消息类型：视频
     */
    public static final String RESP_MESSAGE_TYPE_Video = "video";

    /**
     * 请求消息类型：文本
     */
    public static final String REQ_MESSAGE_TYPE_TEXT = "text";

    /**
     * 请求消息类型：图片
     */
    public static final String REQ_MESSAGE_TYPE_IMAGE = "image";

    /**
     * 请求消息类型：链接
     */
    public static final String REQ_MESSAGE_TYPE_LINK = "link";

    /**
     * 请求消息类型：地理位置
     */
    public static final String REQ_MESSAGE_TYPE_LOCATION = "location";

    /**
     * 请求消息类型：音频
     */
    public static final String REQ_MESSAGE_TYPE_VOICE = "voice";

    /**
     * 请求消息类型：视频
     */
    public static final String REQ_MESSAGE_TYPE_VIDEO = "video";

    /**
     * 请求消息类型：推送
     */
    public static final String REQ_MESSAGE_TYPE_EVENT = "event";

    /**
     * 事件类型：subscribe(订阅)
     */
    public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";

    /**
     * 事件类型：unsubscribe(取消订阅)
     */
    public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";

    /**
     * 事件类型：CLICK(自定义菜单点击事件)
     */
    public static final String EVENT_TYPE_CLICK = "CLICK";

    /**
     * 事件类型：VIEW(自定义菜单URl视图)
     */
    public static final String EVENT_TYPE_VIEW = "VIEW";

    /**
     * 事件类型：LOCATION(上报地理位置事件)
     */
    public static final String EVENT_TYPE_LOCATION = "LOCATION";

    /**
     * 事件类型：LOCATION(上报地理位置事件)
     */
    public static final String EVENT_TYPE_SCAN = "SCAN";

    /**
     *  解析微信发来的请求（XML）
     */
    public  Map<String, String> parseXml(HttpServletRequest request) {
        // 将解析结果存储在HashMap中
        Map<String, String> map = new HashMap<String, String>();

        // 读取输入流
        SAXReader reader = new SAXReader();
        Document document = null;
        InputStream inputStream = null;
        try {
            // 从request中取得输入流
            inputStream = request.getInputStream();
            document = reader.read(inputStream);
            // 得到xml根元素
            Element root = document.getRootElement();
            // 得到根元素的所有子节点
            List<Element> elementList = root.elements();

            // 遍历所有子节点
            elementList.forEach(element -> {
                map.put(element.getName(), element.getStringValue());
            });
        } catch (DocumentException | IOException e) {
            e.printStackTrace();
        } finally {
            // 释放资源
            if(null != inputStream){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return map;
    }

    /**
     * 消息对象转换成xml
     */
    public static String messageToXml(Object obj) {
        XStream xStream = new XStream();
        xStream.alias("xml", obj.getClass());
        return xStream.toXML(obj);
    }
    /**
     * 发送文本消息
     */
    public  String sendText(Map<String,String> map,String text){
        TextMessage textMessage = new TextMessage();
        textMessage.setToUserName(map.get("FromUserName"));
        textMessage.setFromUserName(map.get("ToUserName"));
        textMessage.setContent(text);
        Date date = new Date();
        textMessage.setCreateTime(date.getTime());
        textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
        return MessageUtil.messageToXml(textMessage);
    }
    /**
     * 发送图片
     */
    public  String sendImage(Map<String,String> map){
        Image image =new Image();
        image.setMediaId(map.get("MediaId"));
        PicMessage picMessage =new PicMessage();
        picMessage.setImage(image);
        picMessage.setCreateTime(new Date().getTime());
        picMessage.setToUserName(map.get("FromUserName"));
        picMessage.setFromUserName(map.get("ToUserName"));
        picMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_Image);
        return MessageUtil.messageToXml(picMessage);
    }
    /**
     * 发送图文
     */
    public  String sendImageAndText(Map<String,String> map,News news){
        PicAndTextMessage picMessage =new PicAndTextMessage();
        List<News> list = new ArrayList<>();
        News newsItem  = new News();
        newsItem.setTitle(news.getTitle());
        newsItem.setDescription(news.getDescription());
        newsItem.setPicUrl(news.getPicUrl());
        newsItem.setUrl(news.getUrl());
        list.add(newsItem);
        picMessage.setArticleCount(list.size());
        picMessage.setArticles(list);
        picMessage.setToUserName(map.get("FromUserName"));
        picMessage.setFromUserName(map.get("ToUserName"));
        picMessage.setCreateTime(new Date().getTime());
        picMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS);
        return MessageUtil.messageToXml(picMessage);
    }

    /**
     * 发送模板消息
     */
    public  void sendTemplateMsg(Map<String,String> map){
        TreeMap<String, TreeMap<String, String>> params = new TreeMap<>();

        Weather tempByCity = stringUtil.getTempByCity(config.getCity());

        params.put("hint",TemplateMessage.item(stringUtil.getAmOrPm(),stringUtil.getGRB()));
        params.put("date",TemplateMessage.item(stringUtil.getNowTime(),stringUtil.getGRB()));
        params.put("city",TemplateMessage.item(tempByCity.getCity(),stringUtil.getGRB()));
        params.put("currentWeather",TemplateMessage.item(tempByCity.getCurrentWeather(),stringUtil.getGRB()));
        params.put("type",TemplateMessage.item(tempByCity.getType(),stringUtil.getGRB()));
        params.put("fx",TemplateMessage.item(tempByCity.getFx(),stringUtil.getGRB()));
        params.put("high",TemplateMessage.item(tempByCity.getHigh(),stringUtil.getGRB()));
        params.put("low",TemplateMessage.item(tempByCity.getLow(),stringUtil.getGRB()));
        params.put("day",TemplateMessage.item(String.valueOf(stringUtil.getBetweenDay(config.getDay())),stringUtil.getGRB()));
        params.put("ganmao",TemplateMessage.item(tempByCity.getGanmao(),stringUtil.getGRB()));
        params.put("text",TemplateMessage.item(text,stringUtil.getGRB()));

        // 发送人的openId
        templateMessage.setTouser(map.get("FromUserName"));
        templateMessage.setTopcolor("#FF0000");
        templateMessage.setData(params);
        templateMessage.setTemplate_id(config.getTemplateId());

        RestTemplate restTemplate = new RestTemplate();

        ResponseEntity<String> responseEntity =
                restTemplate.postForEntity(BaseUrl.SEND.replace("ACCESS_TOKEN", getAccessToken()), templateMessage, String.class);

        log.info(responseEntity.toString());
    }
}
